package com.mar.framecompress.impl.zlib;
/* -*-mode:java; c-basic-offset:2; -*- */
import java.nio.ByteBuffer;

import com.jcraft.jzlib.JZlib;
import com.jcraft.jzlib.ZStream;

public class ZlibFacade{
	public static void compress(ByteBuffer rawDataBuf, ByteBuffer outBuff) {
		int err;

		ZStream c_stream = new ZStream();

		err = c_stream.deflateInit(JZlib.Z_DEFAULT_COMPRESSION);
		CHECK_ERR(c_stream, err, "deflateInit");

		c_stream.next_in = rawDataBuf.array();
		c_stream.next_in_index = rawDataBuf.arrayOffset();//TODO: plus position value

		c_stream.next_out = outBuff.array();
		c_stream.next_out_index = outBuff.arrayOffset();

		// encode
		c_stream.avail_in = rawDataBuf.remaining();
		c_stream.avail_out = outBuff.remaining(); // force small buffers
		err = c_stream.deflate(JZlib.Z_NO_FLUSH);
		CHECK_ERR(c_stream, err, "deflate");

		// encode finish
		err = c_stream.deflate(JZlib.Z_FINISH);
		assert (err == JZlib.Z_STREAM_END);
//		CHECK_ERR(c_stream, err, "deflate");

		err = c_stream.deflateEnd();
		
		rawDataBuf.position((int) c_stream.total_in);
		rawDataBuf.flip();
		outBuff.position( (int) c_stream.total_out );
		outBuff.flip();
		
		CHECK_ERR(c_stream, err, "deflateEnd");
	}
	
	public static void decompress(ByteBuffer compressedBuf, ByteBuffer outBuff) {
		ZStream d_stream = new ZStream();

		d_stream.next_in = compressedBuf.array();
		d_stream.next_in_index = compressedBuf.arrayOffset();
		d_stream.next_out = outBuff.array();
		d_stream.next_out_index = outBuff.arrayOffset();

		int err = d_stream.inflateInit();
		CHECK_ERR(d_stream, err, "inflateInit");

		d_stream.avail_in = compressedBuf.remaining();
		d_stream.avail_out = outBuff.remaining();
		err = d_stream.inflate(JZlib.Z_NO_FLUSH);
		assert (err == JZlib.Z_STREAM_END );

		err = d_stream.inflateEnd();
		CHECK_ERR(d_stream, err, "inflateEnd");

		compressedBuf.position((int) d_stream.total_in);
		compressedBuf.flip();
		outBuff.position( (int) d_stream.total_out );
		outBuff.flip();
	}
	
	static void CHECK_ERR(ZStream z, int err, String msg) {
		if (err != JZlib.Z_OK) {
			if (z.msg != null)
				System.out.print(z.msg + " ");
			System.out.println(msg + " error: " + err);
			System.exit(1);
		}
	}
}
